package cn.jiangjiesheng.bootstrap.commons.filter;

import cn.hutool.core.codec.Base64;
import cn.jiangjiesheng.bootstrap.commons.constants.AuthorizationConstants;
import cn.jiangjiesheng.bootstrap.commons.constants.Profiles;
import cn.jiangjiesheng.bootstrap.commons.context.UserInfoContext;
import cn.jiangjiesheng.bootstrap.commons.properties.DevUserMockProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * Created by dev@jiangjiesheng.cn on 2021/9/26  <br/>
 *
 * @author dev@jiangjiesheng.cn
 */
@Configuration
@WebFilter(urlPatterns = "/shengxingapi")
@Slf4j
public class UserInfoInjectFilter extends OncePerRequestFilter {

    @Autowired
    private DevUserMockProperties devUserMockProperties;

    @Value("${spring.profiles.active:dev}")
    private String activeProfile;


    /**
     * Same contract as for {@code doFilter}, but guaranteed to be
     * just invoked once per request within a single request thread.
     * See {@link #shouldNotFilterAsyncDispatch()} for details.
     * <p>Provides HttpServletRequest and HttpServletResponse arguments instead of the
     * default ServletRequest and ServletResponse ones.
     *
     * @param request
     * @param response
     * @param filterChain
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        log.debug("header keys: {}",request.getHeaderNames());
        if (Objects.nonNull(request.getHeader(AuthorizationConstants.AUTHORIZATION_CODE))
                || StringUtils.isNotBlank(request.getHeader("user_id"))) {
            // 上游网关
            UserInfoContext.reset();
            log.debug("processing web filter for authorization, and the accessToken is {}.", request.getHeader(AuthorizationConstants.AUTHORIZATION_CODE));
            final String realName = Base64.decodeStr(request.getHeader("real_name"), StandardCharsets.UTF_8);
            UserInfoContext.UserInfo userInfo = UserInfoContext.UserInfo.builder()
                    .avatar(request.getHeader("avatar"))
                    .enterpriseId(request.getHeader("enterprise_id"))
                    .userId(request.getHeader("user_id"))
                    .enterpriseName(request.getHeader("enterprise_name"))
                    .realName(realName)
                    .isMocked(false)
                    .accessToken(request.getHeader(AuthorizationConstants.AUTHORIZATION_CODE))
                    .build();
            log.debug("userinfo {}", UserInfoContext.getUserInfo());
            UserInfoContext.setUserInfo(userInfo);
            filterChain.doFilter(request, response);
        } else if (Profiles.DEV.equals(activeProfile) && devUserMockProperties.getEnabled()) {
            // 模拟登录
            UserInfoContext.reset();
            log.debug("使用mock用户，详见配置项 shengxing-commons.yaml  -> dev -> mock-user，生效条件: profile=dev 并且 mock-user.enabled=true");
            UserInfoContext.setUserInfo(devUserMockProperties);
            filterChain.doFilter(request, response);
        } else {
            UserInfoContext.reset();
            log.debug("request header `access_token` is not set, mock auth mode is enabled ?");
            if (StringUtils.isNotBlank(request.getParameter("entId"))&&StringUtils.isNotBlank(request.getParameter("userId"))) {
                UserInfoContext.UserInfo userInfo = UserInfoContext.UserInfo.builder()
                        .enterpriseId(request.getParameter("entId"))
                        .userId(request.getParameter("userId"))
                        .isMocked(false)
                        .build();
                UserInfoContext.setUserInfo(userInfo);
            }
            filterChain.doFilter(request, response);
        }
    }
    public static void main(String[] args) {
        String name = "黄志强";
        System.out.println(Base64.decodeStr(Base64.encode(name)));
    }
}


